/* 
对axios进行2次封装一个能发ajax请求的函数
一个能发送ajax请求的函数
1. 统一处理请求异常
2. 异步请求成功的数据不是response, 而是response.data
3. 对post请求参数(请求体参数,可能还有其他请求方式携带请求体 ) 进行ulencode处理, 而不使用默认的json方式(可能后台接口不支持) 因为： 请求体参数默认是json格式。 后台如果不支持json格式参数， 需要转化为ulencode处理
  需要用到库qs
4. 配置请求超时的时间
5. 通过请求头携带token数据


实际上封装主要是用它的请求拦截器，响应拦截器
*/
import axios from 'axios'
import qs from 'qs'
import {
  Indicator,
  Toast,
  MessageBox
} from 'mint-ui';
import store from '../store'
import router from '../router'

// 使用自定义配置新建一个 axios 实例  instance  实际上是Axios的实例 
const instance = axios.create({
  // baseURL: 'http://localhost:4000'有跨域请求问题
  baseURL: '/api', //代理服务器转发请求接收响应处理跨域问题
  timeout: 5000 //4. 配置请求超时的时间 
});

// 拦截器 本质是一个函数
// 添加请求拦截器   请求拦截器  一般只添加成功的函数   传入参数为config
instance.interceptors.request.use(
  config => {
    const {
      method,
      data
    } = config

    // 显示请求loading
    Indicator.open({
      text: '加载中...',
      spinnerType: 'triple-bounce'
    });
    // 获取token
    const token = store.state.user.token
    if (token) { //如果后台返回的数据有token就在请求头里加。token的键名是Authorization。没有token就不加。
      config.headers['Authorization'] = token
    } else {
      // 如果当前接口需要token校验, 但没有token, 不发请求, 进入错误流程
      const needCheck = config.headers.needCheck
      // 如果没有token, 但又需要token校验, 不能发请求
      if (needCheck) {
        throw new Error('没有登陆, 不能请求!')
      }
    }
    //  对post请求参数 进行ulencode处理, 而不使用默认的json方式(可能后台接口不支持)
    if (method.toLowerCase() === 'post') {
      // 若传递过来的参数是对象
      if (data instanceof Object) {
        // 如果传入的post请求参数是对象，则将它转化为urlencoded编码格式
        config.data = qs.stringify(data)
      }
    }

    return config //必须返回个config
  }
)
// 添加响应拦截器   添加成功的函数和失败的函数
instance.interceptors.response.use(
  response => {

    //隐藏请求loading
    Indicator.close();
    //retur response
    //2. 异步请求成功的数据不是response, 而是response.data

    return response.data;
  },
  error => {

    // 隐藏请求loading
    Indicator.close()
    const response = error.response
    // 没发请求的错误
    if (!response) {
      const path = router.currentRoute.path
      if (path !== '/login') {
        // console.log('+++++++')
        router.replace('/login')
        Toast(error.message)
      }
    } else { // 发了请求的错误
      // 如果响应状态码是401, 且当前没在登陆页面, 退出登陆(清除数据) 跳到登陆页面
      if (error.response.status === 401) {
        const path = router.currentRoute.path
        if (path !== '/login') {
          // console.log('-----------')
          store.dispatch('logout')
          router.replace('/login')
          Toast(error.response.data.message || '登陆失效, 请重新登陆')
        }
      } else if (error.response.status === 404) { // status为: 404: 提示访问的资源不存在
        MessageBox('提示', '访问的资源不存在')
      } else {
        // 1. 统一处理请求异常
        MessageBox('提示', '请求出错: ' + error.message)
      }
    }

    // return Promise.reject(error)

    return new Promise(() => {}) //返回一个pending状态的Promise ===>目的：中断Promise链
  }
)

export default instance